﻿using CodeCube.Common;
using CodeCube.Core.DtoModel;
using CodeCube.Core.DtoModel.KTDataTable;
using CodeCube.Core.Extensions;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace CodeCube.Core.Repository
{
    public class SBaseV<T>:DbContext,IBaseV<T> where T:class,new()
    {
        #region 查询操作
        /// <summary>
        /// 获得一条数据
        /// </summary>
        /// <param name="where">Expression<Func<T, bool>></param>
        /// <returns></returns>
        public async Task<ApiResult<T>> GetModelAsync(Expression<Func<T, bool>> where, bool Async = true)
        {
            var res = new ApiResult<T>() { success = false, statusCode = (int)ApiEnum.Error };
            try
            {
                res.data = Async ? await Db.Queryable<T>().Where(where).FirstAsync()
                : Db.Queryable<T>().Where(where).First();
                if (res.data != null && res.data != DBNull.Value)
                {
                    res.success = true;
                }
                else
                {
                    res.data = new T() { };
                }
            }
            catch (Exception ex)
            {
                res.message = ApiEnum.Error.GetEnumText() + ex.Message;
                Logger.Default.ProcessError((int)ApiEnum.Error, ex.Message);
            }
            return res;
        }
        public async Task<ApiResult<T>> GetModelAsync(Expression<Func<T, bool>> where, Expression<Func<T, object>> order, DbOrderEnum orderEnum, bool Async = true)
        {
            var res = new ApiResult<T>() { success = false, statusCode = (int)ApiEnum.Error };
            try
            {
                res.data = Async ? await Db.Queryable<T>().Where(where)
                    .OrderByIF((int)orderEnum == 1, order, SqlSugar.OrderByType.Asc)
                    .OrderByIF((int)orderEnum == 2, order, SqlSugar.OrderByType.Desc).FirstAsync()
                : Db.Queryable<T>().Where(where)
                    .OrderByIF((int)orderEnum == 1, order, SqlSugar.OrderByType.Asc)
                    .OrderByIF((int)orderEnum == 2, order, SqlSugar.OrderByType.Desc).First();
                if (res.data != null && res.data != DBNull.Value)
                {
                    res.success = true;
                }
                else
                {
                    res.data = new T() { };
                }
            }
            catch (Exception ex)
            {
                res.message = ApiEnum.Error.GetEnumText() + ex.Message;
                Logger.Default.ProcessError((int)ApiEnum.Error, ex.Message);
            }
            return res;
        }
        /// <summary>
        /// 获得一条数据
        /// </summary>
        /// <param name="parm">string</param>
        /// <returns></returns>
        public async Task<ApiResult<T>> GetModelAsync(string parm, bool Async = true)
        {

            var res = new ApiResult<T>() { success = false, statusCode = (int)ApiEnum.Error };
            try
            {
                res.data = Async ? await Db.Queryable<T>().Where(parm).FirstAsync()
                : Db.Queryable<T>().Where(parm).First();
                if (res.data != null && res.data != DBNull.Value)
                {
                    res.success = true;
                }
                else
                {
                    res.data = new T() { };
                }
            }
            catch (Exception ex)
            {
                res.message = ApiEnum.Error.GetEnumText() + ex.Message;
                Logger.Default.ProcessError((int)ApiEnum.Error, ex.Message);
            }

            return res;
        }

        /// <summary>
		/// 获得列表——分页
		/// </summary>
		/// <param name="parm">PageParm</param>
		/// <returns></returns>
        public async Task<ApiResult<Page<T>>> GetPagesAsync(PageParm parm, bool Async = true)
        {
            var res = new ApiResult<Page<T>>() { success = false, statusCode = (int)ApiEnum.Error };
            try
            {
                res.data = Async ? await Db.Queryable<T>()
                        .ToPageAsync(parm.page, parm.limit) : Db.Queryable<T>()
                        .ToPage(parm.page, parm.limit);
                res.success = true;
                res.statusCode = (int)ApiEnum.Status;
            }
            catch (Exception ex)
            {
                res.message = ApiEnum.Error.GetEnumText() + ex.Message;
                res.statusCode = (int)ApiEnum.Error;
                Logger.Default.ProcessError((int)ApiEnum.Error, ex.Message);
            }
            return res;
        }

        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="parm">分页参数</param>
        /// <param name="where">条件</param>
        /// <param name="order">排序值</param>
        /// <param name="orderEnum">排序方式OrderByType</param>
        /// <returns></returns>
        public async Task<ApiResult<Page<T>>> GetPagesAsync(PageParm parm, Expression<Func<T, bool>> where,
            Expression<Func<T, object>> order, DbOrderEnum orderEnum, bool Async = true)
        {
            var res = new ApiResult<Page<T>>() { success = false, statusCode = (int)ApiEnum.Error };
            try
            {
                var query = Db.Queryable<T>()
                        .Where(where)
                        .OrderByIF((int)orderEnum == 1, order, SqlSugar.OrderByType.Asc)
                        .OrderByIF((int)orderEnum == 2, order, SqlSugar.OrderByType.Desc);
                res.data = Async ? await query.ToPageAsync(parm.page, parm.limit) : query.ToPage(parm.page, parm.limit);
                res.success = true;
                res.statusCode = (int)ApiEnum.Status;
            }
            catch (Exception ex)
            {
                res.message = ApiEnum.Error.GetEnumText() + ex.Message;
                res.statusCode = (int)ApiEnum.Error;
                Logger.Default.ProcessError((int)ApiEnum.Error, ex.Message);
            }
            return res;
        }
        public virtual async Task<KTDataTable<T>> GetKTDataTableAsync(KTDataTableDto parm, bool Async = true)
        {
            var res = new KTDataTable<T>();
            try
            {
                if (parm.sort != null)
                {
                    res = Async ? await Db.Queryable<T>().ToKTDataTableAsync(parm.pagination.page, parm.pagination.perpage, parm.sort.field, parm.sort.sort) :
                        Db.Queryable<T>().ToKTDataTable(parm.pagination.page, parm.pagination.perpage, parm.sort.field, parm.sort.sort);
                }
                else
                {
                    res = Async ? await Db.Queryable<T>().ToKTDataTableAsync(parm.pagination.page, parm.pagination.perpage) :
                        Db.Queryable<T>().ToKTDataTable(parm.pagination.page, parm.pagination.perpage);
                }
            }
            catch (Exception ex)
            {
                Logger.Default.ProcessError((int)ApiEnum.Error, ex.Message);
            }
            return res;
        }
        public async Task<KTDataTable<T>> GetKTDataTableAsync(KTDataTableDto parm, List<Expression<Func<T, bool>>> where, bool Async = true)
        {
            var res = new KTDataTable<T>();
            try
            {
                var data = Db.Queryable<T>();
                foreach (var wexp in where)
                {
                    data = data.Where(wexp);
                }
                if (parm.sort != null)
                {
                    res = Async ? await data.ToKTDataTableAsync(parm.pagination.page, parm.pagination.perpage, parm.sort.field, parm.sort.sort) :
                        data.ToKTDataTable(parm.pagination.page, parm.pagination.perpage, parm.sort.field, parm.sort.sort);
                }
                else
                {
                    res = Async ? await data.ToKTDataTableAsync(parm.pagination.page, parm.pagination.perpage) :
                        data.ToKTDataTable(parm.pagination.page, parm.pagination.perpage);
                }
            }
            catch (Exception ex)
            {
                Logger.Default.ProcessError((int)ApiEnum.Error, ex.Message);
            }
            return res;
        }
        /// <summary>
		/// 获得列表
		/// </summary>
		/// <param name="parm">PageParm</param>
		/// <returns></returns>
        public async Task<ApiResult<List<T>>> GetListAsync(Expression<Func<T, bool>> where,
            Expression<Func<T, object>> order, DbOrderEnum orderEnum, bool Async = true)
        {
            var res = new ApiResult<List<T>>() { success = false, statusCode = (int)ApiEnum.Error };
            try
            {
                var query = Db.Queryable<T>()
                        .Where(where)
                        .OrderByIF((int)orderEnum == 1, order, SqlSugar.OrderByType.Asc)
                        .OrderByIF((int)orderEnum == 2, order, SqlSugar.OrderByType.Desc);
                res.data = Async ? await query.ToListAsync() : query.ToList();
                res.success = true;
                res.statusCode = (int)ApiEnum.Status;
            }
            catch (Exception ex)
            {
                res.message = ApiEnum.Error.GetEnumText() + ex.Message;
                res.statusCode = (int)ApiEnum.Error;
                Logger.Default.ProcessError((int)ApiEnum.Error, ex.Message);
            }
            return res;
        }

        /// <summary>
        /// 获得列表，不需要任何条件
        /// </summary>
        /// <returns></returns>
        public async Task<ApiResult<List<T>>> GetListAsync(bool Async = true)
        {
            var res = new ApiResult<List<T>>() { success = false, statusCode = (int)ApiEnum.Error };
            try
            {
                res.data = Async ? await Db.Queryable<T>().ToListAsync() : Db.Queryable<T>().ToList();
                res.success = true;
                res.statusCode = (int)ApiEnum.Status;
            }
            catch (Exception ex)
            {
                res.message = ApiEnum.Error.GetEnumText() + ex.Message;
                res.statusCode = (int)ApiEnum.Error;
                Logger.Default.ProcessError((int)ApiEnum.Error, ex.Message);
            }
            return res;
        }
        #endregion
    }
}
